export type RequestHandler = (operation: Operation) => Promise<FetchResult | null>;

export interface GraphQLError {
    /**
     * A message describing the Error for debugging purposes.
     *
     * Enumerable, and appears in the result of JSON.stringify().
     */
    message: string;

    /**
     * An array of { line, column } locations within the source GraphQL document
     * which correspond to this error.
     *
     * Errors during validation often contain multiple locations, for example to
     * point out two things with the same name. Errors during execution include a
     * single location, the field which produced the error.
     *
     * Enumerable, and appears in the result of JSON.stringify().
     */
    locations?: Array<{ line: number; column: number }> | undefined;
}

export declare type OperationVariables = {
    [key: string]: any;
};

/**
 * The result of execution. `data` is the result of executing the
 * query, `extensions` represents additional metadata, `errors` is
 * null if no errors occurred, and is a
 * non-empty array if an error occurred.
 */
export interface ExecutionResult {
    data?: { [key: string]: any };
    // extensions?: { [key: string]: any };
    errors?: GraphQLError[];
}


export interface Operation {
    query: string;
    variables: Record<string, any>;
    operationName?: string;
    // extensions: Record<string, any>;
    // setContext: (context: Record<string, any>) => Record<string, any>;
    // getContext: () => Record<string, any>;
    // toKey: () => string;
}

export type FetchResult<C = Record<string, any>, E = Record<string, any>> = ExecutionResult & {
    extensions?: E;
    context?: C;
};


export declare enum NetworkStatus {
    loading = 1,
    setVariables = 2,
    fetchMore = 3,
    refetch = 4,
    poll = 6,
    ready = 7,
    error = 8,
}

export interface QueryOptions {
    query: any,
    context?: any;
    variables?: {
        [key: string]: any;
    };
    fetchPolicy?: any
}

export interface MutationOptions<T = {
    [key: string]: any;
}> {
    mutation: any,
    context?: any;
    variables?: {
        [key: string]: any;
    };
    fetchPolicy?: any
}

export type QueryResult<T> = {
    data: T;
    errors?: GraphQLError[];
    // loading: boolean;
    // networkStatus: NetworkStatus;
    // stale: boolean;
};
